import java.sql.*;

public class FirstExample {

    private static Connection s_pConnect;
    private static Statement s_pStatement;
    private static PreparedStatement s_pPreparedStatement;
    private static CallableStatement s_pCallableStatement;
    private static ResultSet s_setResult;

    public static void main(String[] args) {

        try {
            /*第一步，加载实现 JDBC 接口的数据库的驱动*/
            Class.forName(Const.JDBC_DRIVER);

            /*这是第二种加载驱动的方式，当时用的是非 JDK 兼容的 JVM 时，使用这种方式进行加载*/
//            Driver dirver = new com.mysql.jdbc.Driver();
//            DriverManager.registerDriver(dirver);

            /*第二步，连接到数据库, 这是其中一种方式，还有另外两个重载方法
             * getConnection(String url)  密码等信息都在 URL 中，不建议使用
             * getConnection(String url, Properties prop)，Properties 中包含了信息键值对
             * */
            s_pConnect = DriverManager.getConnection(Const.MYSQL_URL, Const.USER_NAME, Const.USER_PASSWORD);


            /*第三步，构造一个 Statement ，并通过它执行一个 SQL 语句
             * 这个 Statement 对象可以执行三种类型的操作
             * 1.boolean execute (String SQL)：可使用于创建数据库，创建表等
             * 2.int executeUpdate (String SQL) ：执行 INSERT,UPDATE,DELETE 等操作，返回受影响的行数
             * 3.ResultSetStudy executeQuery(String SQL): 执行 SELECT 操作，返回一组数据
             * */
            String strSql = "SELECT * FROM simpleTable";
            s_pStatement = s_pConnect.createStatement();
            s_setResult = s_pStatement.executeQuery(strSql);

            /*
             * 这个 PreparedSqlStatement 是实现了 Statement , 支持动态的添加参数，比后者更灵活
             * 和 Statement 相同，都拥有三种操作
             * 通过 ? 来作为占位符，通过setXXX 来设置参数。下标从 1 开始
             * 执行 SQL 语句时，不需要再把 SQL 填入。
             * */
//            String strPreparedSql = "SELECT * FROM simpleTable WHERE sname=?";
//            s_pPreparedStatement = s_pConnect.prepareStatement(strPreparedSql);
//            s_pPreparedStatement.setString(1, "小明");
//            s_setResult = s_pPreparedStatement.executeQuery();


            /*
             * CallableStatement 是用来执行存储过程的 Statement
             * 根据存储过程不同有不一样的使用方式，具体参考一下帖子
             * https://www.cnblogs.com/zengjiao/p/6853873.html
             * 当前测试未通过、
             *
             * */
            String strProcedure = "{call getById(?,?)}";
            s_pCallableStatement = s_pConnect.prepareCall(strProcedure);
            s_pCallableStatement.setInt(1, 1);
            s_pCallableStatement.registerOutParameter(2, Types.VARCHAR);
            s_pCallableStatement.execute();
            String strName = s_pCallableStatement.getString(2);
            System.out.println(strName);

            /*第四步，从执行 SQL 之后返回的结果对象中取出查询到内容*/
            while (s_setResult.next()) {
                readContentFromSimpleTableResultSet(s_setResult);
            }

        } catch (SQLException e1) {
            System.out.println(
                    "ErrorCode : " + e1.getErrorCode()
                    + "\r\n"
                    + "ErrorMessage : " + e1.getMessage()
                    + "\r\n"
                    + "SqlState : " + e1.getSQLState()
            );

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            /*第五步，必须关闭释放资源*/
            try {
                if (s_setResult != null) {
                    s_setResult.close();
                }

                if (s_pStatement != null) {
                    s_pStatement.close();
                }

                if (s_pPreparedStatement != null) {
                    s_pPreparedStatement.close();
                }

                if (s_pCallableStatement != null) {
                    s_pCallableStatement.close();
                }

                if (s_pConnect != null) {
                    s_pConnect.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void readContentFromSimpleTableResultSet(ResultSet setResult) {
        try {
            int id = setResult.getInt("id");
            int age = setResult.getInt("age");
            String name = setResult.getString("sname");
            String hobby = setResult.getString("hobby");
            System.out.println(id + " - " + age + " - " + name + " - " + hobby);
        } catch (Exception ex) {
            //
        }
    }
}
